package com.gareve.RainScene.views;

import java.util.Iterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.FPSLogger;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Array;
import com.gareve.RainScene.models.GameWorld;
import com.gareve.RainScene.models.Man;
import com.gareve.RainScene.models.RainDrop;
import com.gareve.RainScene.models.Splash;

public class GameRenderer {
	private final String TAG = GameRenderer.class.getSimpleName();
	public static final float GAME_WIDTH = 100f;
	public static final float GAME_HEIGHT = 75f;
	
	private final Color WATER_BELOW_COLOR = new Color(0f, 0f, 0.6f, 1f);
	private final Color WATER_UPPER_COLOR = new Color(0f, 0f, 0.15f, 1f);
	
	private final Color SKY_BELOW_COLOR = new Color(0.03f, 0.03f, 0.03f, 1f);
	private final Color SKY_UPPER_COLOR = new Color(0.1f, 0.1f, 0.1f, 1f);
	
	private GameWorld gameWorld;
	private int width,height;
	
	//Render objects
	private OrthographicCamera camera;
	private ShapeRenderer shapeRenderer = new ShapeRenderer();
	private SpriteBatch spriteBatch = new SpriteBatch();
	
	//Textures
	private Texture manTexture;
	private TextureRegion manTextures[] = new TextureRegion[Man.FRAME_COUNT];
	
	private AtlasRegion machineRegions[] = new AtlasRegion[8];
	
	//Miscelanea
	FPSLogger fpsLogger = new FPSLogger();
	
	public void render(){
		initCameraAndStuff();
		
		renderBackGround();
		renderMan(gameWorld.man);
		
		renderRain();
		renderDramaticBox(gameWorld.dramaticRect,gameWorld.dramaticReveal);

		fpsLogger.log();
	}

	public GameRenderer() {
		camera = new OrthographicCamera(GAME_WIDTH, GAME_HEIGHT);
		camera.position.x = GAME_WIDTH / 2f;
		camera.position.y = GAME_HEIGHT / 2f;
		camera.update();

		spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, GAME_WIDTH, GAME_HEIGHT);
		
		
		Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		
		loadTextures();
		loadSounds();
	}
	
	public void loadTextures(){
		manTexture = new Texture(Gdx.files.internal("running_man.png"));
		TextureRegion splitResults[][] = TextureRegion.split(manTexture, 512 / 6, 512 / 5);
		
		int index = 0;
		for(int i=0;i<5;i++)
			for(int j=0;j<6;j++)
				manTextures[index++] = splitResults[i][j];
		
		TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("atlas/attacker-hd.txt"));
		 //= atlas.findRegions("attacker-hd");
		
		 Array<AtlasRegion> atlasRegionsTmp = atlas.getRegions();
		
		Gdx.app.log(TAG, String.format("Regions: %d",atlasRegionsTmp.size));
		for (AtlasRegion atlasRegion : atlasRegionsTmp) {
			Gdx.app.log(TAG, String.format("Region: %s",atlasRegion.name));
		}
		
		for(int i=0;i<8;i++)
			machineRegions[i] = atlas.findRegion(String.format("attright-%d",i+1));
	}
	public void loadSounds(){
		
	}

	/**********************
	 *** Render Helpers ***
	 **********************/
	
	private void renderDramaticBox(Rectangle dramaticRectangle,Rectangle dramaticReveal){
		Gdx.gl.glEnable(GL10.GL_BLEND);
		shapeRenderer.begin(ShapeType.FilledRectangle);
			if(dramaticReveal != null){
				shapeRenderer.setColor(0.1f, 0.1f, 0.1f,dramaticReveal.height);
				shapeRenderer.filledRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
			}

			shapeRenderer.setColor(0f, 0f, 0f,1f);
			shapeRenderer.filledRect(0, 0, GAME_WIDTH, dramaticRectangle.height);
			shapeRenderer.filledRect(0, GAME_HEIGHT, GAME_WIDTH, -dramaticRectangle.height);	
		shapeRenderer.end();
		Gdx.gl.glDisable(GL10.GL_BLEND);
	}
	
	private void renderRain(){
		RainDrop rainDrop;		
		
		Gdx.gl.glEnable(GL10.GL_BLEND);
		shapeRenderer.begin(ShapeType.FilledRectangle);
			shapeRenderer.identity();
			shapeRenderer.rotate(0f, 0f, 1, -30f);
			for(int i=1;i<=GameWorld.RAINDROP_COUNT;i++){
				rainDrop = gameWorld.createRainDrop();
				float segmentSize = rainDrop.shape.height / (float)RainDrop.SEGMENT_COUNT;
				
				for(float j = 0;j<RainDrop.SEGMENT_COUNT;j++){
					shapeRenderer.setColor(25f/256f,158f/256f,230f/256f, 1f - 1f / (j+1f));
					shapeRenderer.filledRect(rainDrop.shape.x, rainDrop.shape.y + segmentSize * j, rainDrop.shape.width, segmentSize);
				}
			}
			shapeRenderer.identity();
		shapeRenderer.end();
		Gdx.gl.glDisable(GL10.GL_BLEND);
	}
	
	public void renderSplashes(){
		shapeRenderer.begin(ShapeType.Circle);
		shapeRenderer.setColor(1f,1f,1f, 1f);
		for (Iterator it = gameWorld.splashes.iterator(); it.hasNext();) {
			Splash splash = (Splash) it.next();
			
			if(splash.isAlive() == false)
				it.remove();
			else{
				shapeRenderer.circle(splash.shape.x, splash.shape.y, splash.shape.height, 10);
			}
		}
		shapeRenderer.end();
	}
	
	private void renderBackGround(){
		final float ROAD_MARGIN = 3f;
		
		shapeRenderer.begin(ShapeType.FilledRectangle);						
			shapeRenderer.filledRect(0f,GAME_HEIGHT * 0.15f, GAME_WIDTH, GAME_HEIGHT * 0.15f,
					WATER_BELOW_COLOR,WATER_BELOW_COLOR,WATER_UPPER_COLOR,WATER_UPPER_COLOR);
		shapeRenderer.end();
		
		renderSplashes();
		
		shapeRenderer.begin(ShapeType.FilledRectangle);						
		shapeRenderer.filledRect(0f,GAME_HEIGHT - GAME_HEIGHT * 0.15f, GAME_WIDTH, - GAME_HEIGHT * 0.55f,
				SKY_BELOW_COLOR,SKY_BELOW_COLOR,SKY_UPPER_COLOR,SKY_UPPER_COLOR);
		shapeRenderer.end();
	}
	
	private void initCameraAndStuff(){
		Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		
		Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);		
		shapeRenderer.setProjectionMatrix(camera.combined);
	}
	private void renderMan(Man man){
		if(true){
			shapeRenderer.begin(ShapeType.Rectangle);
				shapeRenderer.setColor(0f,1f,0f,1f);
				shapeRenderer.rect(man.shape.x, man.shape.y, man.shape.width, man.shape.height);
			shapeRenderer.end();
		}
		spriteBatch.begin();
			spriteBatch.setColor(1f, 1f, 1f, 1f);	
			//spriteBatch.draw(manTextures[man.keyFrame], man.shape.x,man.shape.y, man.shape.width, man.shape.height);
			spriteBatch.draw(machineRegions[man.keyFrame%8], man.shape.x,man.shape.y, man.shape.width, man.shape.height);
			
			
			manTextures[man.keyFrame].flip(false, true);
			spriteBatch.setColor(1f, 1f, 1f, 0.3f);
			spriteBatch.draw(manTextures[man.keyFrame], man.shape.x,man.shape.y - man.shape.height, man.shape.width, man.shape.height);
			manTextures[man.keyFrame].flip(false, true);
		spriteBatch.end();
	}
	
	/***************************
	 *** Setters and Getters ***
	 ***************************/
	
	public void setGameWorld(GameWorld gameWorld){
		this.gameWorld = gameWorld;
	}
	
	public void resize(int width,int height){
		this.width = width;
		this.height = height;		
	}
}
